package com.qyc.Microservice.controller;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.qyc.Microservice.dto.result.ResponseResult;

@ResponseResult
@RestController
@RequestMapping("/redis")
public class RedisController {
	
	@Autowired
	private RedisTemplate redisTemplate;
	
	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	
	
	@GetMapping("/getString1")
	@ResponseBody
	@Cacheable(value = "springboot",key="#root.methodName")// "springboot：：getString"他成为了我们的在redis里边的key
	public Map<String, String>  getString() {
//	public String  getString() {
		//1.对于我们的这个value属性来说，它代表的是一块内存区域（例子：类似于我们的d盘，C盘，这时候springboot代表了就是我们的
		//不同区域的存储空间划分
		//2.代表key。这个key是属于springboot这个缓存区域的key
		//3.（当笑话听，主要为让同学更加理解）总结：将我们的内存区域分了一块出来，取名springboot，然后我们将getString这个key存入到了这个springboot磁盘区）
		String string = "Hello world!"+":"+ "11";
		Map<String, String> map = new HashMap<String, String>();
		map.put("1", string);
		//这个sysout会不会每次都打印呢？不会，因为第一次进行helloworld返回的时候，就已经将我们的string存入到了
		//我们的redis缓存中，在30s内进行该方法的访问时，不会走正常的逻辑，而是会走 @Cacheable 的内部实现逻辑
		//也就是说，sysout之后的代码不会被执行到。方便啊，真方便啊
		System.out.println("如果打印这条信息，代表我们的返回值是没有从缓存里边取出的");
		return map;
	}

	@GetMapping("/getStrArgs")
	@Cacheable(value = "springboot",key="#root.args[0]")// "springboot：：【传参的值】"他成为了我们的在redis里边的key
	public String getStrArgs(@RequestParam(name="name") String name) {
		//1.对于我们的这个value属性来说，它代表的是一块内存区域（例子：类似于我们的d盘，C盘，这时候springboot代表了就是我们的
		//不同区域的存储空间划分
		//2.代表key。这个key是属于springboot这个缓存区域的key
		//3.（当笑话听，主要为让同学更加理解）总结：将我们的内存区域分了一块出来，取名springboot，然后我们将getString这个key存入到了这个springboot磁盘区）
		String string = "Hello world!"+":"+ name;
		//这个sysout会不会每次都打印呢？不会，因为第一次进行helloworld返回的时候，就已经将我们的string存入到了
		//我们的redis缓存中，在30s内进行该方法的访问时，不会走正常的逻辑，而是会走 @Cacheable 的内部实现逻辑
		//也就是说，sysout之后的代码不会被执行到。方便啊，真方便啊
		System.out.println("如果打印这条信息，代表我们的返回值是没有从缓存里边取出的");
		return string;
	}

	
	/**
	 * redisTemplate & stringRedisTemplate
	 */
	@PostMapping("/set")
	public void set() {
		redisTemplate.opsForValue().set("myName","zhangsan");
		redisTemplate.opsForHash().put("hashValue","map1","map1-1");
		stringRedisTemplate.opsForValue().set("youName", "LiSi1",Duration.ofSeconds(20));
	}
	
	@GetMapping("/get")
	public void get() {
		String myname = (String)redisTemplate.opsForValue().get("myName");
		Map hashValue = redisTemplate.opsForHash().entries("hashValue");
		String youName = (String)redisTemplate.opsForValue().get("youName");
		String youName1 = stringRedisTemplate.opsForValue().get("youName");
		System.out.println("myname:"+ myname);
		System.out.println("youName:"+ youName);//没有获取到值，说明两者的数据是不共通的
		System.out.println("youName1:"+ youName1);
		System.out.println("hashValue:"+hashValue);
	}
}
